home *** CD-ROM | disk | FTP | other *** search
- /* Hey Emacs this is -*- C -*-
- *
- * $Id: pstricks.trm,v 1.6 1995/12/20 21:48:09 drd Exp $
- */
-
- /* GNUPLOT - pstricks.trm */
- /*
- * Copyright (C) 1990 - 1993
- *
- * Permission to use, copy, and distribute this software and its
- * documentation for any purpose with or without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation.
- *
- * Permission to modify the software is granted, but not the right to
- * distribute the modified code. Modifications are to be distributed
- * as patches to released version.
- *
- * This software is provided "as is" without express or implied warranty.
- *
- * This file is included by ../term.c.
- *
- * This terminal driver supports:
- * The PSTricks macros for LaTeX.
- *
- * AUTHORS
- * David Kotz
- *
- * Raymond Toy toy@soho.crd.ge.com
- * Modified the eepic.trm file to use PSTricks macros instead.
- *
- * 20 Mar 93:
- * Utilized many suggestions from Gisli Ottarsson
- * (gisli@liapunov.eecs.umich.edu) to create a new version.
- * Should also work with TeX as well as LaTeX.
- *
- * If you have PSTricks version 0.91, #define OLD_PST to
- * get the right dots.
- *
- * Added a really ugly hack (enabled by default) to print
- * "nice" numbers for axis labels. This should really be at
- * a higher level in the code, but I'm lazy right now.
- *
- * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
- *
- */
-
- /*
- * This file contains the PSTricks terminal driver, intended for use with the
- * pstricks.sty macro package for LaTeX. This is an alternative to the
- * eepic and latex driver. You need pstricks.sty, and, of course, a printer
- * that understands PostScript. Ghostscript understands Postscript too.
- *
- * PSTricks is available via anonymous ftp from the /pub directory
- * at Princeton.EDU. This driver definitely does not come close to
- * using the full capability of the PSTricks package.
- */
- /*
- * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
- */
-
- #ifndef GOT_DRIVER_H
- #include "driver.h"
- #endif
-
- #ifdef TERM_REGISTER
- register_term(pstricks)
- #endif
-
- #ifdef TERM_PROTO
- TERM_PUBLIC void PSTRICKS_init __P((void));
- TERM_PUBLIC void PSTRICKS_graphics __P((void));
- TERM_PUBLIC void PSTRICKS_text __P((void));
- TERM_PUBLIC void PSTRICKS_linetype __P((int linetype));
- TERM_PUBLIC void PSTRICKS_move __P((unsigned int x, unsigned int y));
- TERM_PUBLIC void PSTRICKS_point __P((unsigned int x, unsigned int y, int number));
- TERM_PUBLIC void PSTRICKS_vector __P((unsigned int ux, unsigned int uy));
- TERM_PUBLIC void PSTRICKS_arrow __P((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, TBOOLEAN head));
- TERM_PUBLIC void PSTRICKS_put_text __P((unsigned int x, unsigned int y, char str[]));
- TERM_PUBLIC int PSTRICKS_justify_text __P((enum JUSTIFY mode));
- TERM_PUBLIC int PSTRICKS_text_angle __P((int angle));
- TERM_PUBLIC void PSTRICKS_reset __P((void));
-
- #define PSTRICKS_XMAX 10000.0
- #define PSTRICKS_YMAX 10000.0
-
- #define PSTRICKS_HTIC 150
- #define PSTRICKS_VTIC 200
- #define PSTRICKS_HCHAR 160
- #define PSTRICKS_VCHAR 420
- #endif /* TERM_PROTO */
-
- #ifndef TERM_PROTO_ONLY
- #ifdef TERM_BODY
- static void PSTRICKS_endline __P((void));
-
- static float PSTRICKS_xscale = 1.0;
- static float PSTRICKS_yscale = 1.0;
- static float PSTRICKS_posx;
- static float PSTRICKS_posy;
- enum JUSTIFY PSTRICKS_justify = LEFT;
- static int PSTRICKS_angle = 0;
-
- #define PSTRICKS_TINY_DOT 0.00025 /* A tiny dot */
-
- /* POINTS */
- #define PSTRICKS_POINT_TYPES 12 /* we supply more point types */
- static char *PSTRICKS_points[] =
- {
- "\\PST@Diamond",
- "\\PST@Plus",
- "\\PST@Square",
- "\\PST@Cross",
- "\\PST@Circle",
- "\\PST@Triangle",
- "\\PST@Pentagon",
- "\\PST@Filldiamond",
- "\\PST@Fillsquare",
- "\\PST@Filltriangle",
- "\\PST@Fillcircle",
- "\\PST@Fillpentagon"
- };
-
- /* LINES */
- #define PSTRICKS_NUMLINES 6 /* number of linetypes below */
- static char *PSTRICKS_lines[] =
- {
- "\\PST@Border",
- "\\PST@Axes",
- "\\PST@Solid",
- "\\PST@Dashed",
- "\\PST@Dotted",
- "\\PST@LongDash"
- };
-
- static int PSTRICKS_type; /* current line type */
- static TBOOLEAN PSTRICKS_inline = FALSE;/* are we in the middle of a line */
- static void PSTRICKS_endline(); /* terminate any line in progress */
- static int PSTRICKS_linecount = 0; /* number of points in line so far */
-
- #define PSTRICKS_LINEMAX 100 /* max value for linecount */
-
- /*
- * Handle options
- */
-
- static int PST_hack_text = TRUE; /* Hack text on */
- static int PST_unit_plot = FALSE; /* Unit-sized plot off */
-
- TERM_PUBLIC void
- PSTRICKS_options()
- {
- if (!END_OF_COMMAND) {
- if (almost_equals(c_token, "no$hacktext")) {
- PST_hack_text = FALSE;
- c_token++;
- } else if (almost_equals(c_token, "u$nit")) {
- PST_unit_plot = TRUE;
- c_token++;
- }
- }
- }
-
- TERM_PUBLIC void
- PSTRICKS_init()
- {
- PSTRICKS_posx = PSTRICKS_posy = 0;
- PSTRICKS_linetype(-1);
- fprintf(outfile, "%% GNUPLOT: LaTeX picture using PSTRICKS macros\n");
- }
-
-
- TERM_PUBLIC void
- PSTRICKS_graphics()
- {
- fprintf(outfile, "%% Define new PST objects, if not already defined\n");
-
- fprintf(outfile, "\\ifx\\PSTloaded\\undefined\n");
- fprintf(outfile, "\\def\\PSTloaded{t}\n");
-
- fprintf(outfile, "\\psset{arrowsize=.01 3.2 1.4 .3}\n");
- fprintf(outfile, "\\psset{dotsize=.01}\n");
-
- fprintf(outfile, "\\catcode`@=11\n\n");
-
- /* Define line type objects */
- fprintf(outfile, "\\newpsobject{PST@Border}{psline}{linewidth=.0015,linestyle=solid}\n");
- fprintf(outfile, "\\newpsobject{PST@Axes}{psline}{linewidth=.0015,linestyle=dotted,dotsep=.004}\n");
- fprintf(outfile, "\\newpsobject{PST@Solid}{psline}{linewidth=.0015,linestyle=solid}\n");
- fprintf(outfile, "\\newpsobject{PST@Dashed}{psline}{linewidth=.0015,linestyle=dashed,dash=.01 .01}\n");
- fprintf(outfile, "\\newpsobject{PST@Dotted}{psline}{linewidth=.0025,linestyle=dotted,dotsep=.008}\n");
- fprintf(outfile, "\\newpsobject{PST@LongDash}{psline}{linewidth=.0015,linestyle=dashed,dash=.02 .01}\n");
-
- /* Define point objects */
-
- #ifdef OLD_PST
- /* PSTricks version 0.91 had x and diamond dot types */
- fprintf(outfile, "\\newpsobject(PST@Diamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=diamond}\n");
- fprintf(outfile, "\\newpsobject(PST@Filldiamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=diamond*}\n");
- fprintf(outfile, "\\newpsobject{PST@Cross}{psdots}{linewidth=.001,linestyle=solid,dotstyle=x}\n");
- #else
- /* Newer versions use rotated plus and square to get the x and diamond dots */
- fprintf(outfile, "\\newpsobject{PST@Diamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square,dotangle=45}\n");
- fprintf(outfile, "\\newpsobject{PST@Filldiamond}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square*,dotangle=45}\n");
- fprintf(outfile, "\\newpsobject{PST@Cross}{psdots}{linewidth=.001,linestyle=solid,dotstyle=+,dotangle=45}\n");
- #endif
-
- fprintf(outfile, "\\newpsobject{PST@Plus}{psdots}{linewidth=.001,linestyle=solid,dotstyle=+}\n");
- fprintf(outfile, "\\newpsobject{PST@Square}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square}\n");
- fprintf(outfile, "\\newpsobject{PST@Circle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=o}\n");
- fprintf(outfile, "\\newpsobject{PST@Triangle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=triangle}\n");
- fprintf(outfile, "\\newpsobject{PST@Pentagon}{psdots}{linewidth=.001,linestyle=solid,dotstyle=pentagon}\n");
- fprintf(outfile, "\\newpsobject{PST@Fillsquare}{psdots}{linewidth=.001,linestyle=solid,dotstyle=square*}\n");
- fprintf(outfile, "\\newpsobject{PST@Fillcircle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=*}\n");
- fprintf(outfile, "\\newpsobject{PST@Filltriangle}{psdots}{linewidth=.001,linestyle=solid,dotstyle=triangle*}\n");
- fprintf(outfile, "\\newpsobject{PST@Fillpentagon}{psdots}{linewidth=.001,linestyle=solid,dotstyle=pentagon*}\n");
-
- /* Define arrow object */
- fprintf(outfile, "\\newpsobject{PST@Arrow}{psline}{linewidth=.001,linestyle=solid}\n");
-
- fprintf(outfile, "\\catcode`@=12\n\n");
- fprintf(outfile, "\\fi\n");
-
- /* Set the scaled plot size, if it's not a unit plot */
- if (!PST_unit_plot) {
- fprintf(outfile, "\\psset{unit=%fin,xunit=%fin,yunit=%fin}\n",
- 5.0 * PSTRICKS_xscale,
- 5.0 * PSTRICKS_xscale,
- 3.0 * PSTRICKS_yscale);
- }
-
- fprintf(outfile, "\\pspicture(0,0)(1,1)\n");
- fprintf(outfile, "\\ifx\\nofigs\\undefined\n");
- fprintf(outfile, "\\catcode`@=11\n\n");
- }
-
-
- TERM_PUBLIC void
- PSTRICKS_text()
- {
- PSTRICKS_endline();
- fprintf(outfile, "\\catcode`@=12\n");
- fprintf(outfile, "\\fi\n");
- fprintf(outfile, "\\endpspicture\n");
- }
-
-
- TERM_PUBLIC void
- PSTRICKS_linetype(linetype)
- int linetype;
- {
- PSTRICKS_endline();
-
- if (linetype >= PSTRICKS_NUMLINES - 2)
- linetype %= (PSTRICKS_NUMLINES - 2);
-
- PSTRICKS_type = linetype;
- }
-
-
-
- TERM_PUBLIC void
- PSTRICKS_move(x, y)
- unsigned int x;
- unsigned int y;
- {
- PSTRICKS_endline();
-
- PSTRICKS_posx = x / PSTRICKS_XMAX;
- PSTRICKS_posy = y / PSTRICKS_YMAX;
- }
-
-
- TERM_PUBLIC void
- PSTRICKS_point(x, y, number) /* version of line_and_point */
- unsigned x;
- unsigned y;
- int number;
- {
- PSTRICKS_move(x, y);
-
- /* Print the character defined by 'number'; number < 0 means
- to use a dot, otherwise one of the defined points. */
-
- if (number < 0) {
- fprintf(outfile, "\\qdisk(%.4f,%.4f){%.4f}\n",
- x / PSTRICKS_XMAX,
- y / PSTRICKS_YMAX,
- PSTRICKS_TINY_DOT);
- } else {
- fprintf(outfile, "%s(%.4f,%.4f)\n",
- PSTRICKS_points[number % PSTRICKS_POINT_TYPES],
- x / PSTRICKS_XMAX,
- y / PSTRICKS_YMAX);
- }
- }
-
-
- TERM_PUBLIC void
- PSTRICKS_vector(ux, uy)
- unsigned ux;
- unsigned uy;
- {
- if (!PSTRICKS_inline) {
- PSTRICKS_inline = TRUE;
-
- /* Start a new line. This depends on line type */
- fprintf(outfile, "%s(%.4f,%.4f)\n", PSTRICKS_lines[PSTRICKS_type + 2],
- PSTRICKS_posx, PSTRICKS_posy);
- PSTRICKS_linecount = 1;
- } else {
- /*
- * Even though we are in middle of a path,
- * we may want to start a new path command.
- * If they are too long then latex will choke.
- */
- if (PSTRICKS_linecount++ >= PSTRICKS_LINEMAX) {
- /* fprintf(outfile, "\n"); */
- fprintf(outfile, "%s(%.4f,%.4f)\n", PSTRICKS_lines[PSTRICKS_type + 2],
- PSTRICKS_posx, PSTRICKS_posy);
- PSTRICKS_linecount = 1;
- }
- }
- PSTRICKS_posx = ux / PSTRICKS_XMAX;
- PSTRICKS_posy = uy / PSTRICKS_YMAX;
- fprintf(outfile, "(%.4f,%.4f)\n", PSTRICKS_posx, PSTRICKS_posy);
- }
-
- static void
- PSTRICKS_endline()
- {
- if (PSTRICKS_inline) {
- fprintf(outfile, "\n");
- PSTRICKS_inline = FALSE;
- }
- }
-
-
- TERM_PUBLIC void
- PSTRICKS_arrow(sx, sy, ex, ey, head)
- unsigned int sx;
- unsigned int sy;
- unsigned int ex;
- unsigned int ey;
- TBOOLEAN head;
- {
- fprintf(outfile, "\\PST@Arrow%s(%.4f,%.4f)(%.4f,%.4f)\n",
- head ? "{->}" : "",
- sx / PSTRICKS_XMAX,
- sy / PSTRICKS_YMAX,
- ex / PSTRICKS_XMAX,
- ey / PSTRICKS_YMAX);
-
- PSTRICKS_posx = ex / PSTRICKS_XMAX;
- PSTRICKS_posy = ey / PSTRICKS_YMAX;
- }
-
- /*
- * A really ugly hack!!!
- *
- * This function takes an input string and hacks it up. If the
- * input string starts with a number, it converts the number into a
- * TeX style number including exponential notation. Thus, if
- * the input is the string "3.14159e3 is a number", then
- * the output is "$3.14159\cdot 10^{3}$ is a number", so that TeX
- * will produce something nice.
- *
- * This is basically meant for producing axis labels that look nice.
- *
- * What a hack!
- */
-
-
- static char *
- PSTRICKS_hack_text(s)
- char s[];
- {
- double value;
- char *ends;
- static char hack[BUFSIZ];
-
- /*
- * Does the string start with a number?
- */
-
- value = strtod(s, &ends);
-
- if (s == ends) {
- /*
- * This doesn't start a number, so just copy the string over
- */
-
- strcpy(hack, s);
- } else {
- char *ptr;
-
- /*
- * We have a number! Check to see if the number
- * is in scientific notation
- */
-
- strncpy(hack, s, ends - s);
- hack[ends - s] = '\0';
-
- ptr = strchr(hack, 'e');
- if (ptr == NULL) {
- ptr = strchr(hack, 'E');
- }
-
- if (ptr != NULL) {
- /*
- * Exponential notation! Let's get the mantissa and exponent separately
- */
-
- double man_val;
- int expo_val;
-
- *ptr = '\0';
-
- man_val = atof(hack);
- expo_val = atoi(ptr + 1);
-
- if (man_val == 0) {
- sprintf(hack, "0");
- } else if (man_val == 1) {
- sprintf(hack, "$10^{%d}$", expo_val);
- } else if (man_val == (int) man_val) {
- if (expo_val == 1) {
- sprintf(hack, "$%d$", (int) man_val);
- } else {
- sprintf(hack, "$%d \\times 10^{%d}$", (int) man_val, expo_val);
- }
- } else {
- if (expo_val == 1) {
- sprintf(hack, "$%f$", man_val);
- } else {
- sprintf(hack, "$%f \\times 10^{%d}$", man_val, expo_val);
- }
- }
- }
-
- /*
- * Copy anything that's left of the string
- */
-
- strcat(hack, ends);
- }
-
- return hack;
- }
-
- TERM_PUBLIC void
- PSTRICKS_put_text(x, y, str)
- unsigned int x;
- unsigned int y;
- char str[];
- {
- PSTRICKS_endline();
-
- /* Skip this if the string is empty */
-
- if (strlen(str) > 0) {
- fprintf(outfile, "\\rput");
-
- /* Set justification */
-
- switch (PSTRICKS_justify) {
- case LEFT:
- fprintf(outfile, "[l]");
- break;
- case CENTRE:
- break;
- case RIGHT:
- fprintf(outfile, "[r]");
- break;
- }
-
- /* Set text angle */
-
- switch (PSTRICKS_angle) {
- case 0:
- break;
- case 1:
- fprintf(outfile, "{L}");
- break;
- }
-
- /* Set reference position and text */
-
- fprintf(outfile, "(%.4f,%.4f)",
- x / PSTRICKS_XMAX,
- y / PSTRICKS_YMAX);
- if (PST_hack_text) {
- char *hack;
-
- /* Hack leading numbers to something nice for TeX */
-
- hack = PSTRICKS_hack_text(str);
- fprintf(outfile, "{%s}\n", hack);
- } else {
- fprintf(outfile, "{%s}\n", str);
- }
- }
- }
-
-
-
- TERM_PUBLIC int
- PSTRICKS_justify_text(mode)
- enum JUSTIFY mode;
- {
- PSTRICKS_justify = mode;
- return (TRUE);
- }
-
- TERM_PUBLIC int
- PSTRICKS_text_angle(angle)
- int angle;
- {
- PSTRICKS_angle = angle;
- return (TRUE);
- }
-
- TERM_PUBLIC void
- PSTRICKS_reset()
- {
- PSTRICKS_endline();
- PSTRICKS_posx = PSTRICKS_posy = 0;
- }
-
- #endif /* TERM_BODY */
-
- #ifdef TERM_TABLE
-
- TERM_TABLE_START(pstricks_driver)
- "pstricks", "LaTeX picture environment with PSTricks macros",
- PSTRICKS_XMAX, PSTRICKS_YMAX, PSTRICKS_VCHAR, PSTRICKS_HCHAR,
- PSTRICKS_VTIC, PSTRICKS_HTIC, PSTRICKS_options, PSTRICKS_init, PSTRICKS_reset,
- PSTRICKS_text, null_scale, PSTRICKS_graphics, PSTRICKS_move, PSTRICKS_vector,
- PSTRICKS_linetype, PSTRICKS_put_text, PSTRICKS_text_angle,
- PSTRICKS_justify_text, PSTRICKS_point, PSTRICKS_arrow, set_font_null
- TERM_TABLE_END(pstricks_driver)
-
- #undef LAST_TERM
- #define LAST_TERM pstricks_driver
-
- #endif /* TERM_TABLE */
- #endif /* TERM_PROTO_ONLY */
-
- /*
- * NAME: pstricks
- *
- * OPTIONS: hacktext|nohacktext (default hacktext) <-- ugly hack to give
- * nice numbers
- * unit|nounit (default nounit) <-- some kind of unscaled plot
- *
- * SUPPORTS: LaTeX picture environment with PSTricks macros
- *
- * Further Info:
- * This driver is intended for use with the
- * pstricks.sty macro package for LaTeX. This is an alternative to the
- * eepic and latex driver. You need pstricks.sty, and, of course, a printer
- * that understands PostScript. Ghostscript understands Postscript too.
- *
- * PSTricks is available via anonymous ftp from the /pub directory
- * at Princeton.EDU. This driver definitely does not come close to
- * using the full capability of the PSTricks package.
- *
- * If you have PSTricks version 0.91, #define OLD_PST to
- * get the right dots.
- *
- * My adds:
- * I don't know whether pstricks will work with LaTeX2e but feel it might
- * be obsoleted by a 2e package rather soon.
- *
- */
-